# main.py
import asyncio
import os

from config.config import Config
from src.audio_processor import AudioRecorder
from src.speech_recognizer import BaiduASR
from src.chat_processor import DeepSeekChat
from src.tts_processor import EdgeTTS
import pygame


class VoiceAssistant:
    """语音助手主类"""

    def __init__(self):
        self.config = Config()
        self.asr = BaiduASR(self.config)
        self.chat = DeepSeekChat(self.config)
        self.tts = EdgeTTS(self.config)
        self.is_awake = False  # 唤醒状态
        pygame.mixer.init()

    def _cleanup_temp_files(self):
        """清理临时音频文件"""
        temp_dir = self.config.TEMP_DIR
        if os.path.exists(temp_dir):
            for filename in os.listdir(temp_dir):
                if filename.endswith(('.wav', '.mp3')):
                    file_path = os.path.join(temp_dir, filename)
                    try:
                        # 尝试多次删除，处理文件被占用的情况
                        import time
                        for attempt in range(3):
                            try:
                                os.remove(file_path)
                                print(f"已删除临时文件：{file_path}")
                                break
                            except PermissionError:
                                if attempt < 2:
                                    time.sleep(0.5)  # 等待文件释放
                                    continue
                                else:
                                    print(f"文件被占用，跳过删除：{file_path}")
                    except Exception as e:
                        print(f"无法删除文件 {file_path}: {e}")


    async def wait_for_wake_word(self, recorder):
        """等待唤醒词"""
        print("小帕正在待机中，请说'你好小帕'来唤醒我...")
        
        while not self.is_awake:
            try:
                # 监听唤醒词
                audio_file = "cache/wake_word.wav"
                recorder.listen_for_wake_word(audio_file)
                
                # 识别唤醒词
                if text := self.asr.recognize(audio_file):
                    print(f"检测到语音：{text}")
                    
                    # 检查是否包含唤醒词
                    if self._is_wake_word(text):
                        print("\n检测到唤醒词！小帕已唤醒")
                        self.is_awake = True
                        
                        # 播放欢迎音频
                        if os.path.exists("static/welcome.mp3"):
                            pygame.mixer.music.load("static/welcome.mp3")
                            pygame.mixer.music.play()
                            while pygame.mixer.music.get_busy():
                                pygame.time.Clock().tick(10)
                        
                        print("你好，我是小帕，有什么想跟我说的吗？")
                        break
                        
            except KeyboardInterrupt:
                print("\n退出系统")
                raise
            except Exception as e:
                print(f"唤醒检测异常：{e}")
                continue
    
    def _is_wake_word(self, text):
        """检查是否为唤醒词"""
        if not text:
            return False
        
        wake_words = ["你好小帕", "小帕", "你好", "小帕你好"]
        text_lower = text.lower().replace(" ", "")
        
        for wake_word in wake_words:
            if wake_word in text_lower:
                return True
        return False

    async def conversation_loop(self, recorder):
        """对话循环"""
        while self.is_awake:
            try:
                # 录音和识别
                audio_file = "cache/recording.wav"
                recorder.record(audio_file)

                if text := self.asr.recognize(audio_file):
                    print(f"\n识别结果：{text}")
                    
                    # 检查是否要进入休眠
                    if self._is_sleep_command(text):
                        print("小帕进入休眠模式...")
                        self.is_awake = False
                        break

                    # 生成并播放回复
                    if response := await self.chat.generate_reply(text):
                        await self.tts.synthesize(response)
                else:
                    print("未能识别有效内容，请重试")

            except KeyboardInterrupt:
                print("\n退出系统")
                raise
            except Exception as e:
                print(f"对话处理异常：{e}")
                continue
    
    def _is_sleep_command(self, text):
        """检查是否为休眠命令"""
        if not text:
            return False
        
        sleep_commands = ["再见", "拜拜", "休眠", "睡觉", "关闭", "退出"]
        text_lower = text.lower().replace(" ", "")
        
        for command in sleep_commands:
            if command in text_lower:
                return True
        return False

    async def main_loop(self):
        """主循环：等待唤醒 -> 对话 -> 休眠"""
        print("小帕语音助手启动成功！")
        
        try:
            with AudioRecorder(self.config) as recorder:
                while True:
                    try:
                        # 等待唤醒
                        if not self.is_awake:
                            await self.wait_for_wake_word(recorder)
                        
                        # 进入对话模式
                        if self.is_awake:
                            await self.conversation_loop(recorder)
                            
                    except KeyboardInterrupt:
                        print("\n用户中断，正在退出...")
                        break
                    except Exception as e:
                        print(f"系统错误：{e}")
                        continue
                        
        except KeyboardInterrupt:
            print("\n用户中断，正在退出...")
        except Exception as e:
            print(f"系统错误：{e}")
        finally:
            print("正在清理临时文件...")
            # 停止pygame mixer以释放音频文件
            try:
                import pygame
                pygame.mixer.quit()
            except:
                pass
            self._cleanup_temp_files()
            print("小帕语音助手已退出")


if __name__ == "__main__":
    assistant = VoiceAssistant()
    asyncio.run(assistant.main_loop())
